package xcore

import (
	"context"
	"database/sql"
	"gitee.com/xfrm/middleware/xlog"
)

func AllPageIterator(ctx context.Context, fun string, page func(off, lim int) (int, error), itfun func(itcount int)) error {
	return AllPageIteratorLimit(ctx, 200, fun, page, itfun)
}
func AllPageIteratorLimit(ctx context.Context, limit int, fun string, page func(off, lim int) (int, error), itfun func(itcount int)) error {
	offset := 0
	if limit < 1 {
		limit = 200
	}
	for {
		xlog.Infof(ctx, "%s PageIterator: offset:%d,limit:%d", fun, offset, limit)
		len, err := page(offset, limit+1)
		if err == sql.ErrNoRows {
			xlog.Warnf(ctx, "%s select norow :%s", fun, err)
			return nil
		}
		if err != nil {
			xlog.Warnf(ctx, "%s select error err:%s", fun, err)
			return err
		}
		count := len
		if len > limit {
			count = limit
		}
		itfun(count)
		if len <= limit {
			break
		}
		offset += limit
	}
	return nil
}
func OnePageItems(ctx context.Context, fun string, offset, limit int32, page func(off, lim int32) (int32, error), itfun func(itcount int32)) (int32, bool, error) {
	if offset < 0 {
		offset = 0
	}
	if limit <= 0 {
		limit = 20
	}
	len, err := page(offset, limit+1)
	if err == sql.ErrNoRows {
		xlog.Warnf(ctx, "%s select norow :%s", fun, err)
		return offset, false, nil
	}
	if err != nil {
		xlog.Warnf(ctx, "%s select error err:%s", fun, err)
		return offset, false, err
	}
	count := len
	more := false
	if count > limit {
		count = limit
		more = true
	}
	itfun(count)
	offset += limit
	return offset, more, nil
}

//返回总共循环几次， 是否超过最大循环次数，以及错误
func LoopPage(ctx context.Context, maxLoop, fromOffset, defaultLimit int64, page func(ctx2 context.Context, offset int64, limit int64) (int64, bool, error)) (int, bool, error) {
	var offset = fromOffset
	if offset < 0 {
		offset = 0
	}
	if defaultLimit < 1 {
		defaultLimit = 100
	}
	var loop = 0
	for {
		maxLoop--
		if maxLoop < 0 {
			return loop, true, nil
		}
		nextOffset, more, err := page(ctx, offset, defaultLimit)
		loop++
		if err != nil {
			return loop, false, err
		}
		if !more {
			return loop, false, nil
		}
		offset = nextOffset
	}
	return loop, true, nil
}
